#ifndef USERS_H_INCLUDED
#define USERS_H_INCLUDED
#include <vector>
#include <string>
#include <fstream>
#include <istream>
#include <ostream>
#include <User.h>
#include <cstdio>
#include <algorithm>
/*
        User类对象持久化
        包括文件的读取与储存
*/
class UserManage
{
public:

        vector<User> allUsers;
        UserManage()
        {
                allUsers.reserve(100000);//faster
                //     allUsers.resize(100000);
                load();
        }
        /**
                function for test
        */
        void printAllUser4Test()
        {
                int length = allUsers.size();
                for (int i = 0; i < length; i++)
                {
                        cout << " uid = " << allUsers[i].uid << " pw = " << allUsers[i].pw;
                        cout << " level = " << allUsers[i].level;
                        cout << endl;
                }
        }
        int  printAllUserFormal()
        {
                cout << "成员数量：" << allUsers.size() << endl;
                int length = allUsers.size();
                for (int i = 0; i < length; i++)
                {
                        cout << " rownum:" << i << "\t";
                        string lvName;
                        if (allUsers[i].level == 1)
                        {
                                lvName = " 管理员";
                        }
                        else
                        {
                                lvName = " 同学";
                        }
                        cout << "\t用户名：\t" << allUsers[i].uid;

                        if (allUsers[i].uid.length() < 8)
                        {
                                cout << "\t";
                        }
                        cout << " \t\t用户等级：" << lvName << endl;
                }
                return length;
        }
        User * searchByUid(string uid)
        {
                int length = allUsers.size();
                for (int i = 0; i < length; i++)
                {
                        if (uid == allUsers[i].uid)
                        {
                                return &allUsers[i];
                        }
                }
                return NULL;
        }
        void add(User *_user)
        {
                allUsers.push_back(*_user);
                sort(allUsers.begin(), allUsers.end(), [&](User x, User y)
                {
                        return x.uid < y.uid;
                });
                save();
        }
        /**
                标记删除用户
        */
        void rm(int index)
        {
                int length = allUsers.size();
                if (index < length && index >= 0)
                {
                        allUsers[index].uid = "-";
                        allUsers[index].pw = "-";
                        allUsers[index].level = -2048;
                        save();
                }
        }
        /**
                实际删除用户
        */
        void deleteUselessUser()
        {
                int length = allUsers.size();
                int i = 0;
                while (i < length)
                {
                        if (allUsers[i].level == -2048)
                        {
                                allUsers[i] = allUsers[length - 1];
                                allUsers.pop_back();
                                length--;
                                i = -1;
                        }
                        i++;
                }
                save();
        }
        void load()
        {
                string ch;
                User *temUser;
                allUsers.clear();//删除所有元素
                string filePath = "userFile.txt";
                ifstream fin;
                fin.open(filePath.c_str(), ios_base::in );
                if (fin.is_open())
                {
                        int length = 0;
                        fin >> length;
                        getline(fin, ch); //吃掉回车
                        for (int i = 0; i < length; i++)
                        {
                                temUser = new User();
                                getline(fin, temUser->uid);
                                getline(fin, temUser->pw);
                                fin >> temUser->level;
                                getline(fin, ch); //吃掉回车

                                //密码解密
                                temUser->pw = decry(temUser->pw);

                                allUsers.push_back(*temUser);
                        }

                        fin.close();
                }




        }

        void save()
        {

                string filePath = "userFile.txt";
                ofstream fout(filePath.c_str(), ios_base::out );
                if (!fout.is_open())
                {
                        cerr << "无法打开" << filePath << endl;
                        exit(EXIT_FAILURE);
                }
                int length = allUsers.size();
                fout << length << endl;
                for (int i = 0; i < length; i++)
                {
                        fout << allUsers[i].uid << endl;
                        //加密
                        string encrypw = encry(allUsers[i].pw);

                        fout << encrypw << endl;
                        fout << allUsers[i].level << endl;
                }
                fout.flush();
                fout.close();

        }

        User * binaryLoginCheck(string uid, string pw, int l, int r)
        {
                int m = (l + r) / 2;
                if (l > r) return NULL;
                if (allUsers[m].uid == uid)
                {
                        if (allUsers[m].pw == pw)
                        {
                                return &allUsers[m];
                        }
                        return NULL;
                }
                if (uid < allUsers[m].uid)
                {
                        return binaryLoginCheck(uid, pw, l, m - 1);
                }
                else
                {
                        return binaryLoginCheck(uid, pw, m + 1, r);
                }
        }

        User * loginCheck(string uid, string pw)
        {
                int length = allUsers.size();
                /*
                for (int i = 0 ; i < length ; i ++)
                {
                        if (uid == allUsers[i].uid && pw == allUsers[i].pw)
                        {
                                return &allUsers[i];
                        }
                }
                return NULL;
                */
                return binaryLoginCheck(uid, pw, 0, length - 1);
        }


        //简单加密
        string encry(string source)
        {
                string target  = source;
                int targetLen = target.size();
                for (int i = 0; i < targetLen; i++)
                {
                        target[i] += 50 * i + i * i;
                }
                return target;
        }
        //解密
        string decry(string source)
        {
                string target  = source;
                int targetLen = target.size();
                for (int i = 0; i < targetLen; i++)
                {
                        target[i] -= 50 * i + i * i;

                }

                return target;
        }

};




#endif // USERS_H_INCLUDED
